package com.YHVision.qiuzhike.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.YHVision.qiuzhike.mapper.CompanyFavourMapper;
import com.YHVision.qiuzhike.mapper.CompanyThumbMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.YHVision.qiuzhike.common.ErrorCode;
import com.YHVision.qiuzhike.constant.CommonConstant;
import com.YHVision.qiuzhike.exception.ThrowUtils;
import com.YHVision.qiuzhike.mapper.CompanyMapper;
import com.YHVision.qiuzhike.model.dto.company.CompanyQueryRequest;
import com.YHVision.qiuzhike.model.entity.Company;
import com.YHVision.qiuzhike.model.entity.CompanyFavour;
import com.YHVision.qiuzhike.model.entity.CompanyThumb;
import com.YHVision.qiuzhike.model.entity.User;
import com.YHVision.qiuzhike.model.vo.CompanyVO;
import com.YHVision.qiuzhike.model.vo.UserVO;
import com.YHVision.qiuzhike.service.CompanyService;
import com.YHVision.qiuzhike.service.UserService;
import com.YHVision.qiuzhike.utils.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 企业服务实现
 *
 * @author <a href="">YHVision-小y</a>
 * @from <a href="todo">爱编程学习圈</a>
 */
@Service
@Slf4j
public class CompanyServiceImpl extends ServiceImpl<CompanyMapper, Company> implements CompanyService {

    @Resource
    private UserService userService;

    @Resource
    private CompanyThumbMapper companyThumbMapper;

    @Resource
    private CompanyFavourMapper companyFavourMapper;

    /**
     * 校验数据
     *
     * @param company
     * @param add      对创建的数据进行校验
     */
    @Override
    public void validCompany(Company company, boolean add) {
        ThrowUtils.throwIf(company == null, ErrorCode.PARAMS_ERROR);
        // todo 从对象中取值
        String companyName = company.getCompanyName();
        String companyProfile = company.getCompanyProfile();
        // 创建数据时，参数不能为空
        if (add) {
            // todo 补充校验规则
            ThrowUtils.throwIf(StringUtils.isBlank(companyName), ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(StringUtils.isBlank(companyProfile), ErrorCode.PARAMS_ERROR);
        }
        // 修改数据时，有参数则校验
        // todo 补充校验规则
        if (StringUtils.isNotBlank(companyName)) {
            ThrowUtils.throwIf(companyName.length() > 50, ErrorCode.PARAMS_ERROR, "名称过长");
        }
        if (StringUtils.isNotBlank(companyProfile)) {
            ThrowUtils.throwIf(companyProfile.length() > 250, ErrorCode.PARAMS_ERROR,"企业简介描述过长");
        }
    }

    /**
     * 获取查询条件
     *
     * @param companyQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<Company> getQueryWrapper(CompanyQueryRequest companyQueryRequest) {
        QueryWrapper<Company> queryWrapper = new QueryWrapper<>();
        if (companyQueryRequest == null) {
            return queryWrapper;
        }
        // todo 从对象中取值
        Long id = companyQueryRequest.getId();
        Long notId = companyQueryRequest.getNotId();
        String searchText = companyQueryRequest.getSearchText();
        String sortField = companyQueryRequest.getSortField();
        String sortOrder = companyQueryRequest.getSortOrder();
        String companyName = companyQueryRequest.getCompanyName();
        String companyProfile = companyQueryRequest.getCompanyProfile();
        List<String> industryList = companyQueryRequest.getIndustry();
        Long userId = companyQueryRequest.getUserId();
        // todo 补充需要的查询条件
        // 从多字段中搜索
        if (StringUtils.isNotBlank(searchText)) {
            // 需要拼接查询条件
            queryWrapper.and(qw -> qw.like("companyName", searchText).or().like("companyProfile", searchText));
        }
        // 模糊查询
        queryWrapper.like(StringUtils.isNotBlank(companyName), "companyName", companyName);
        queryWrapper.like(StringUtils.isNotBlank(companyProfile), "companyProfile", companyProfile);
        // JSON 数组查询
        if (CollUtil.isNotEmpty(industryList)) {
            for (String tag : industryList) {
                queryWrapper.like("tags", "\"" + tag + "\"");
            }
        }
        // 精确查询
        queryWrapper.ne(ObjectUtils.isNotEmpty(notId), "id", notId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);
        // 排序规则
        queryWrapper.orderBy(SqlUtils.validSortField(sortField),
                sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }

    /**
     * 获取企业封装
     *
     * @param company
     * @param request
     * @return
     */
    @Override
    public CompanyVO getCompanyVO(Company company, HttpServletRequest request) {
        // 对象转封装类
        CompanyVO companyVO = CompanyVO.objToVo(company);

        // todo 可以根据需要为封装对象补充值，不需要的内容可以删除
        // region 可选
        // 1. 关联查询用户信息
        Long userId = company.getUserId();
        User user = null;
        if (userId != null && userId > 0) {
            user = userService.getById(userId);
        }
        UserVO userVO = userService.getUserVO(user);
        companyVO.setUser(userVO);
        // 2. 已登录，获取用户点赞、收藏状态
        long companyId = company.getId();
        User loginUser = userService.getLoginUserPermitNull(request);
        if (loginUser != null) {
            // 获取点赞
            QueryWrapper<CompanyThumb> companyThumbQueryWrapper = new QueryWrapper<>();
            companyThumbQueryWrapper.in("companyId", companyId);
            companyThumbQueryWrapper.eq("userId", loginUser.getId());
            CompanyThumb companyThumb = companyThumbMapper.selectOne(companyThumbQueryWrapper);
            companyVO.setHasThumb(companyThumb != null);
            // 获取收藏
            QueryWrapper<CompanyFavour> companyFavourQueryWrapper = new QueryWrapper<>();
            companyFavourQueryWrapper.in("companyId", companyId);
            companyFavourQueryWrapper.eq("userId", loginUser.getId());
            CompanyFavour companyFavour = companyFavourMapper.selectOne(companyFavourQueryWrapper);
            companyVO.setHasFavour(companyFavour != null);
        }
        // endregion

        return companyVO;
    }

    /**
     * 分页获取企业封装
     *
     * @param companyPage
     * @param request
     * @return
     */
    @Override
    public Page<CompanyVO> getCompanyVOPage(Page<Company> companyPage, HttpServletRequest request) {
        List<Company> companyList = companyPage.getRecords();
        Page<CompanyVO> companyVOPage = new Page<>(companyPage.getCurrent(), companyPage.getSize(), companyPage.getTotal());
        if (CollUtil.isEmpty(companyList)) {
            return companyVOPage;
        }
        // 对象列表 => 封装对象列表
        List<CompanyVO> companyVOList = companyList.stream().map(company -> {
            return CompanyVO.objToVo(company);
        }).collect(Collectors.toList());

        // todo 可以根据需要为封装对象补充值，不需要的内容可以删除
        // region 可选
        // 1. 关联查询用户信息
        Set<Long> userIdSet = companyList.stream().map(Company::getUserId).collect(Collectors.toSet());
        Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
                .collect(Collectors.groupingBy(User::getId));
        // 2. 已登录，获取用户点赞、收藏状态
        Map<Long, Boolean> companyIdHasThumbMap = new HashMap<>();
        Map<Long, Boolean> companyIdHasFavourMap = new HashMap<>();
        User loginUser = userService.getLoginUserPermitNull(request);
        if (loginUser != null) {
            Set<Long> companyIdSet = companyList.stream().map(Company::getId).collect(Collectors.toSet());
            loginUser = userService.getLoginUser(request);
            // 获取点赞
            QueryWrapper<CompanyThumb> companyThumbQueryWrapper = new QueryWrapper<>();
            companyThumbQueryWrapper.in("companyId", companyIdSet);
            companyThumbQueryWrapper.eq("userId", loginUser.getId());
            List<CompanyThumb> companyCompanyThumbList = companyThumbMapper.selectList(companyThumbQueryWrapper);
            companyCompanyThumbList.forEach(companyCompanyThumb -> companyIdHasThumbMap.put(companyCompanyThumb.getCompanyId(), true));
            // 获取收藏
            QueryWrapper<CompanyFavour> companyFavourQueryWrapper = new QueryWrapper<>();
            companyFavourQueryWrapper.in("companyId", companyIdSet);
            companyFavourQueryWrapper.eq("userId", loginUser.getId());
            List<CompanyFavour> companyFavourList = companyFavourMapper.selectList(companyFavourQueryWrapper);
            companyFavourList.forEach(companyFavour -> companyIdHasFavourMap.put(companyFavour.getCompanyId(), true));
        }
        // 填充信息
        companyVOList.forEach(companyVO -> {
            Long userId = companyVO.getUserId();
            User user = null;
            if (userIdUserListMap.containsKey(userId)) {
                user = userIdUserListMap.get(userId).get(0);
            }
            companyVO.setUser(userService.getUserVO(user));
            companyVO.setHasThumb(companyIdHasThumbMap.getOrDefault(companyVO.getId(), false));
            companyVO.setHasFavour(companyIdHasFavourMap.getOrDefault(companyVO.getId(), false));
        });
        // endregion

        companyVOPage.setRecords(companyVOList);
        return companyVOPage;
    }

}
